package com.huiying.service.Impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.huiying.context.BaseContext;
import com.huiying.entity.dto.CommentDTO;
import com.huiying.entity.dto.CommentPageDTO;
import com.huiying.entity.entity.Comment;
import com.huiying.entity.entity.Favorite;
import com.huiying.entity.entity.Tag;
import com.huiying.entity.result.PageResult;
import com.huiying.entity.vo.CommentVO;
import com.huiying.entity.vo.ParentComment;
import com.huiying.mapper.*;
import com.huiying.service.CommonService;
import com.huiying.service.LikePersistenceService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: lsh
 * @Date: 2024/12/03/21:30
 * @Description: 通用接口实现类
 */
@Service
public class CommonServiceImpl implements CommonService {

    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DemandMapper demandMapper;
    @Autowired
    private WorkMapper workMapper;
    @Autowired
    private LikeMapper likeMapper;
    @Autowired
    private FavoriteMapper favoriteMapper;
    @Autowired
    private ReadMapper readMapper;

    @Autowired
    private LikePersistenceService likePersistenceService;

    @Qualifier("taskExecutor")
    @Autowired
    private TaskExecutor taskExecutor;

    /**
     *  查询标签列表
     * @return: java.util.List<com.fx.entity.Tag>
     */
    @Override
    public List<Tag> getTags() {
        return tagMapper.getTags();
    }


    // 点赞操作
    public boolean like(Long contentId, String contentType) {
        Long userId = BaseContext.getCurrentId();
        String key = "";

        if (Objects.equals(contentType, "0")) {
            key = "demand" + contentId;
        } else if (Objects.equals(contentType, "1")) {
            key = "work" + contentId;
        }

        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        Boolean isMember = setOps.isMember(key, String.valueOf(userId));
        if (Boolean.TRUE.equals(isMember)) {
            return false; // 用户已经点赞
        } else {
            // 用户未点赞，添加到集合中
            setOps.add(key, String.valueOf(userId));
            redisTemplate.expire(key, 1, TimeUnit.DAYS);  // 设置过期时间

            // 异步保存点赞数据到数据库
            taskExecutor.execute(() -> likePersistenceService.saveLikeToMySQL(contentId, contentType)); // 异步执行
            return true;
        }
    }

    // 取消点赞操作
    public boolean unLike(Long contentId, String contentType) {
        Long userId = BaseContext.getCurrentId();
        String key = "";

        if (Objects.equals(contentType, "0")) {
            key = "demand" + contentId;
        } else if (Objects.equals(contentType, "1")) {
            key = "work" + contentId;
        }

        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        Boolean isMember = setOps.isMember(key, String.valueOf(userId));
        if (Boolean.TRUE.equals(isMember)) {
            setOps.remove(key, String.valueOf(userId));  // 移除用户点赞

            // 异步执行取消点赞，等待执行结果
            taskExecutor.execute(() -> likePersistenceService.saveLikeToMySQL(contentId, contentType));
            return true;
        }
        return false;
    }

    /**
     * 获取点赞数
     * @param contentId 内容ID（可以是需求单ID或作品ID）
     * @param contentType 内容类型（如：DEMAND 或 WORK）
     * @return 点赞数
     */
    public long countLikes(Long contentId, String contentType) {
        // 动态生成Redis的key
        String key = contentType.toLowerCase() + contentId;
        SetOperations<String, String> setOps = redisTemplate.opsForSet();

        // 直接从MySQL获取点赞数
        long likeCount = likeMapper.countLikesByContentId(contentId, contentType);

        // 获取数据库中的点赞用户ID列表
        List<Long> likedUserIds = likeMapper.getUserIdsByContentId(contentId, contentType);

        // 将数据库中的用户ID同步到Redis
        Set<String> userIdSet = new HashSet<>();
        for (Long userId : likedUserIds) {
            userIdSet.add(String.valueOf(userId));  // 转换为String类型并添加到Redis的Set中
        }

        // 只有当userIdSet不为空时，才将其添加到Redis
        if (!userIdSet.isEmpty()) {
            // 将用户ID集合存入Redis
            redisTemplate.opsForSet().add(key, userIdSet.toArray(new String[0]));
            redisTemplate.expire(key, 1, TimeUnit.DAYS);  // 设置过期时间
        }

        // 返回点赞数
        return likeCount;
    }


    /**
     * 用户收藏内容（需求单或作品）
     * @param contentId 内容ID（需求单或作品的ID）
     * @param contentType 内容类型（DEMAND 或 WORK）
     * @return: 是否成功收藏
     */
    @Override
    public Boolean collect(Long contentId, String contentType) {
        Long userId = BaseContext.getCurrentId();

        // 检查是否已收藏
        Favorite favorite = favoriteMapper.getByContentIdAndUserId(contentId, userId, contentType);

        if (favorite == null) {
            // 创建收藏对象
            favorite = Favorite.builder()
                    .userId(userId)
                    .contentId(contentId)
                    .favoriteType(contentType)
                    .createTime(LocalDateTime.now())
                    .build();
            // 插入收藏记录
            favoriteMapper.insert(favorite);
            return true;
        }
        return false; // 已收藏，操作无效
    }

    /**
     * 用户取消收藏内容（需求单或作品）
     * @param contentId 内容ID（需求单或作品的ID）
     * @param contentType 内容类型（DEMAND 或 WORK）
     * @return: 是否成功取消收藏
     */
    public Boolean unCollect(Long contentId, String contentType) {
        Long userId = BaseContext.getCurrentId();

        // 检查是否已收藏
        Favorite favorite = favoriteMapper.getByContentIdAndUserId(contentId, userId, contentType);
        if (favorite != null) {
            // 删除收藏记录
            favoriteMapper.delete(contentId, userId, contentType);
            return true;
        }
        return false; // 未收藏，操作无效
    }

    @Autowired
    private CommentMapper commentMapper;

    /**
     * 新增评论
     * @param commentDTO 评论数据传输类
     * @return: void
     */
    @Override
    public void addComment(CommentDTO commentDTO) {
        Long userId = BaseContext.getCurrentId();  // 获取当前用户ID

        // 将DTO数据转换为实体
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDTO, comment);
        comment.setUserId(userId);
        comment.setCreatedTime(LocalDateTime.now());

        // 如果是回复，设置回复用户
        if (commentDTO.getParentId() != null) {
            Long reliedUserId = commentMapper.getRepliedUserIdByCommentId(commentDTO.getParentId());
            comment.setRepliedUserId(reliedUserId);  // 根据 parentId 获取被回复的用户
        }

        // 插入评论到数据库
        commentMapper.insertComment(comment);
    }

    /**
     * 评论分页查询
     * @param commentPageDTO 评论数据传输类
     * @return: com.fx.result.PageResult
     */
    @Override
    public PageResult pageQuery(CommentPageDTO commentPageDTO) {
        // 启动分页查询
        PageHelper.startPage(commentPageDTO.getPage(), commentPageDTO.getPageSize());

        // 查询父评论（没有 parent_id 的评论）
        List<ParentComment> comments = commentMapper.getParentComments(commentPageDTO.getContentId());

        // 获取所有父评论的 ID
        List<Long> parentIds = comments.stream()
                .map(ParentComment::getId)
                .collect(Collectors.toList());

        // 查询所有父评论的子评论
        List<ParentComment> replies = new ArrayList<>();
        if (!parentIds.isEmpty()) {
            replies = commentMapper.getRepliesByParentIds(parentIds);
        }

        // 将查询到的父评论构建成 CommentVO 对象
        List<CommentVO> commentVOList = new ArrayList<>();
        for (ParentComment comment : comments) {
            CommentVO commentVO = new CommentVO();
            BeanUtils.copyProperties(comment, commentVO);  // 将父评论的属性复制到 CommentVO

            // 获取该父评论的所有子评论
            List<CommentVO> replyVOList = new ArrayList<>();
            for (ParentComment reply : replies) {
                if (reply.getParentId().equals(comment.getId())) {
                    CommentVO replyVO = new CommentVO();
                    BeanUtils.copyProperties(reply, replyVO);  // 将子评论的属性复制到 CommentVO
                    replyVOList.add(replyVO);
                }
            }

            // 设置子评论到父评论的 replies 属性中
            commentVO.setReplies(replyVOList);

            // 将构建好的父评论（包括子评论）添加到最终结果列表
            commentVOList.add(commentVO);
        }

        return new PageResult(commentVOList.size(), commentVOList);
    }


    /**
     * 浏览记录分页查询
     * @param page 页数
     * @param pageSize 页面大小
     * @param contentType 内容类型
     * @return: com.fx.result.PageResult
     */
    public PageResult getViewList(Integer page, Integer pageSize, String contentType) {
        Long userId = BaseContext.getCurrentId();

        // 根据用户ID和内容类型获取浏览记录的ID（支持需求单和作品）
        List<Long> contentIds = readMapper.getContentId(userId, contentType);

        if (contentIds.isEmpty()) {
            // 如果没有浏览记录，直接返回空结果
            return new PageResult(0, new ArrayList<>());
        }

        // 开始分页查询
        PageHelper.startPage(page, pageSize);

        // 根据内容类型查询相应的数据
        Page<?> result = null;
        if ("0".equals(contentType)) {
            result = demandMapper.pageQueryByIds(contentIds);  // 查询需求单
        } else if ("1".equals(contentType)) {
            result = workMapper.pageQueryByIds(contentIds);  // 查询作品
        } else {
            // 如果内容类型未知，可以抛出异常或返回空
            result = new Page<>();
        }

        long total = result != null? result.getTotal() : 0;
        return new PageResult(total, result);
    }

    /**
     * 查看用户收藏列表
     * @param page 页数
     * @param pageSize 每页数量
     * @param contentType 内容类型，0为需求单，1为作品
     * @return PageResult 分页结果
     */
    public PageResult getCollectList(Integer page, Integer pageSize, String contentType) {
        Long userId = BaseContext.getCurrentId();  // 获取当前登录用户的ID

        // 根据用户ID和内容类型获取收藏记录的ID（支持需求单和作品）
        List<Long> contentIds = favoriteMapper.getContentId(userId, contentType);

        if (contentIds.isEmpty()) {
            // 如果没有收藏记录，直接返回空结果
            return new PageResult(0, new ArrayList<>());
        }

        // 开始分页查询
        PageHelper.startPage(page, pageSize);

        // 根据内容类型查询相应的数据
        Page<?> result = null;
        if ("0".equals(contentType)) {
            // 查询需求单的收藏记录
            result = demandMapper.pageQueryByIds(contentIds);
        } else if ("1".equals(contentType)) {
            // 查询作品的收藏记录
            result = workMapper.pageQueryByIds(contentIds);
        } else {
            // 如果内容类型未知，可以返回空或抛出异常
            result = new Page<>();
        }

        long total = result != null ? result.getTotal() : 0;
        return new PageResult(total, result);
    }
}
